#include "rtsp_live_stream.h"
#include "sample_comm.h"

#include <unistd.h>

h264LiveStream::h264LiveStream(int vencChn) : chn(vencChn)
{
}

h264LiveStream::~h264LiveStream()
{
}

int h264LiveStream::liveStreamInit()
{
    return 0;
}

int h264LiveStream::liveStreamDestory()
{
    return 0;
}

int h264LiveStream::readFrame(char *in_buf, int in_buf_size,uint32_t* pts)
{
    ot_venc_stream stream = {};
    ot_venc_chn_status stat = {};

    do
    {
        td_s32 s32Ret = ss_mpi_venc_query_status(chn, &stat);
        if (s32Ret != TD_SUCCESS)
        {
            sample_print("error ss_mpi_venc_query_status %x\n", s32Ret);
            return -1;
        }

        if (stat.cur_packs == 0)
        {
            usleep(20 * 1000);
        }
    } while (stat.cur_packs == 0);

    stream.pack = (ot_venc_pack *)malloc(sizeof(ot_venc_pack) * stat.cur_packs);
    if (stream.pack == TD_NULL)
    {
        sample_print("malloc %d stream pack failed! \n", stat.cur_packs);
        return -1;
    }

    /* step 2.4 : call mpi to get one-frame stream */
    stream.pack_cnt = stat.cur_packs;
    td_s32 s32Ret = ss_mpi_venc_get_stream(chn, &stream, -1);
    if (s32Ret != TD_SUCCESS)
    {
        free(stream.pack);
        stream.pack = TD_NULL;
        sample_print("ss_mpi_venc_get_stream failed with %#x!\n", s32Ret);
        return -1;
    }

    /*copy data */
    int length = 0;
    for (td_u32 j = 0; j < stream.pack_cnt; j++)
    {
        if(length + stream.pack[j].len - stream.pack[j].offset > (td_u32)in_buf_size){
            sample_print("error frame bufer is not enough\n");
            length = -1;
            break;
        }

        memcpy(in_buf + length, stream.pack[j].addr + stream.pack[j].offset, stream.pack[j].len - stream.pack[j].offset);
        length += stream.pack[j].len - stream.pack[j].offset;
    }
    *pts = stream.pack[0].pts&0xFFFFFFFF;

    /* step 2.6 : release stream */
    s32Ret = ss_mpi_venc_release_stream(chn, &stream);
    if (s32Ret != TD_SUCCESS)
    {
        sample_print("ss_mpi_venc_release_stream failed!\n");
        free(stream.pack);
        stream.pack = TD_NULL;
        return -1;
    }

    /* step 2.7 : free pack nodes */
    free(stream.pack);
    return length;
}

int h264LiveStream::reqIDRFrame()
{
    td_s32 s32Ret = ss_mpi_venc_request_idr(chn,TD_FALSE);
    if(TD_SUCCESS != s32Ret){
        sample_print("ss_mpi_venc_request_idr failed! %x\n",s32Ret);
        return -1;
    }

    return 0;
}